const { AsyncParallelBailHook, SyncHook } = require('tapable');

class Animal {
  constructor() {
    this.hooks = {
      eat0: new SyncHook(['food']),
      eat: new AsyncParallelBailHook(['food']),
    };
  }

  // 绑定钩子函数
  tap() {
    this.hooks.eat.tapPromise('Animal', (food) => new Promise((resolve) => {
      setTimeout(() => {
        console.log('eat1-1', food);
        resolve(); // 此处为 undefined 进入到下一个回调
      }, 1000);
    }));
    this.hooks.eat.tapPromise('Animal', (food) => new Promise((resolve) => {
      setTimeout(() => {
        console.log('eat1-2', food);
        resolve('eat1-2'); // 这个回调完成后直接触发最后回调
      }, 1000);
    }));
    this.hooks.eat.tapPromise('Animal', (food) => new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('eat1-3', food);
        // eslint-disable-next-line prefer-promise-reject-errors
        reject('eat1-3');
      }, 3000);
    }));
    this.hooks.eat0.tap('Animal', (food) => {
      console.log('eat0-1', food);
    });
  }

  // 调用钩子函数
  start(params) {
    this.hooks.eat.promise(params).then(() => {
      console.log('end');
    }).catch((error) => {
      console.log('error', error);
    });
    this.hooks.eat0.call(params);
  }
}

const cat = new Animal();

cat.tap();
cat.start('鱼🐟');
